package com.okcl.manager.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.okcl.common.exception.BusinessException;
import com.okcl.manager.constant.RedisKeyConstants;
import com.okcl.manager.properties.MinioProperties;
import com.okcl.manager.service.CommonService;
import com.okcl.model.vo.common.ResultCodeEnum;
import com.okcl.model.vo.system.ValidateCodeVo;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class CommonServiceImpl implements CommonService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private MinioProperties minioProperties;

    /**
     * 生成验证码
     *
     * @return
     */
    @Override
    public ValidateCodeVo genderateValidateCode() {
        //定义图形验证码的长、宽、验证码字符数、干扰线宽度
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(200, 100, 4, 20);
        String codeValue = captcha.getCode();
        String imageBase64 = captcha.getImageBase64Data();
        String codeKey = UUID.randomUUID().toString().replace("-", "");
        ValidateCodeVo validateCodeVo = new ValidateCodeVo();
        String captchaKey = RedisKeyConstants.VALIDATE_CODE_KEY + codeKey;
        //将验证码保存到redis中
        stringRedisTemplate.opsForValue().set(captchaKey, codeValue, 5, TimeUnit.MINUTES);
        validateCodeVo.setCodeKey(codeKey);
        validateCodeVo.setCodeValue(imageBase64);
        return validateCodeVo;
    }

    /**
     * 上传文件
     *
     * @param file
     * @return
     */
    @Override
    public String upload(MultipartFile file) {
        try {
            //创建minio客户端
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(minioProperties.getEndpoint())
                    .credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
                    .build();
            //创建bucket
            boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProperties.getBucketName()).build());
            if (!found) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket("default-bucket" + UUID.randomUUID().toString()).build());
            } else {
                log.info("Bucket '{}' already exists.", minioProperties.getBucketName());
            }
            //原始文件名
            String originalFilename = file.getOriginalFilename();//提取文件扩展名
            //提取文件扩展名
            String fileExtension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            //新文件名
            String fileName = UUID.randomUUID().toString().replace("-", "") + fileExtension;
            //指定文件路径
            String datePath = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
            //文件路径
            String objectName = datePath + "/" + fileName;
            //文件上传
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(minioProperties.getBucketName())
                            .object(objectName)
                            .stream(file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build());
            //获取文件上传路径
            String url = minioProperties.getEndpoint() + "/" + minioProperties.getBucketName() + "/" + objectName;
            log.info("文件上传成功，返回的url为：{}", url);
            return url;
        } catch (Exception e) {
            log.error("上传文件异常", e);
            throw new BusinessException(ResultCodeEnum.SYSTEM_ERROR);
        }
    }
}
